/**
 * 孔号类
 */
export class RingNumbers {
	static ringsRE = /^((\d{1,5}-\d{1,5},)|(\d{1,5},))*((\d{1,5}-\d{1,5})|(\d{1,5}))$/
	constructor(oRingsString) {
		if (!oRingsString) {
			return
		}
		if (typeof oRingsString !== 'string') throw ('孔号标识应该为字符串')
		if (oRingsString.length < 1) throw ('孔号标识的长度应该大于零')
		if (!RingNumbers.ringsRE.test(oRingsString)) {
			uni.showToast({
				title:'孔号不符合规则',
				icon:'none'
			})
			throw ('孔号不符合规则')
		}
		this.oRingsString = oRingsString
		this.value = this.values()
		this.stringValue = this.toString()
	}

	/**
	 * 设置
	 * @param {number[]} values 
	 */
	setValues(values) {
		if (!Array.isArray(values)) throw ('values不是数组')
		this.stringValue = undefined
		values = values.map(String)
		const s = new Set(values) // 去重
		this.value = [...s].sort((a, b) => a-b)
	}

	/**
	 * 已排序的孔号数值数组
	 * @returns number[]
	 */
	values() {
		if (this.value) return this.value
		if (!this.oRingsString) return []
		const ringRangs = this.oRingsString.split(',').map(rr => { // 分段
			let [s, e = s, r = []] = rr.split('-')
			console.log(s, e, r)
			debugger
			while (+s <= +e) r.push(s++)
			return r
		})
		const s = new Set([].concat(...ringRangs)) // 去重
		this.value = [...s].sort((a,b)=>a-b) // 排序
		return this.value
	}

	/**
	 * 孔号的区段描述字符串，类似 201-205,206,208-210,212,...
	 * @returns string
	 */
	toString() {
		if (this.stringValue) return this.stringValue
		if (!this.value) return
		if (this.value.length === 1) {
			return this.value[0]
		}
		this.ringRangs = []
		let range = [undefined, undefined]
		this.value.forEach((v, i) => {
			if (!range[0]) {
				range = [v, v]
			} else {
				if (v - range[1] === 1) {
					range[1] = v
				} else {
					this.ringRangs.push([...range])
					range = [v, v]
				}
			}
			if (i === this.value.length - 1) {
				this.ringRangs.push([...range])
			}
		})
		debugger
		this.ringRangsStr = this.ringRangs.map(rr => rr[0] === rr[1] ? String(rr[0]) : rr.join('-'))
		this.stringValue = this.ringRangsStr.join(',')
		return this.stringValue
	}

	/**
	 * 设置上层和下层孔号的开头字母
	 * @param {String[]} upperLayer 
	 * @param {String[]} lowerLayer 
	 */
	setLayer(upperLayer, lowerLayer) {
		if (!Array.isArray(upperLayer)) throw ('上层孔号的字母标识集应该是数组')
		if (!Array.isArray(lowerLayer)) throw ('下层孔号的字母标识集应该是数组')
		this.upperLayer = upperLayer
		this.lowerLayer = lowerLayer
		this.__calcRings()
	}
	/**
	 * 更改成外侧：w... 内侧:n...
	 * @param {Object} upperLayer
	 * @param {Object} lowerLayer
	 */
	setLayer_v2(upperLayer, lowerLayer) {
		if (!Array.isArray(upperLayer)) throw ('上层孔号的字母标识集应该是数组')
		if (!Array.isArray(lowerLayer)) throw ('下层孔号的字母标识集应该是数组')
		this.upperLayer = upperLayer
		this.lowerLayer = lowerLayer
		this.__calcRings_v2()
	}
	__calcRings_v2(){
		if (!this.upperLayer) throw ('请先设置孔号的字母标识集')
		this.rings = []
		this.lRings = [[], []]
		if (!this.value) return
		this.upperLayer.forEach((lt, li) => {
			this.lRings[0][li] = []
			this.value.forEach(num => {
				const ro = { lt, num, ly: 'upper', ln: num + lt + (li + 1)}
				this.rings.push(ro)
				this.lRings[0][li].push(ro)
			})
		})
		this.lRings[0] = this.lRings[0].reverse()
		this.lowerLayer.forEach((lt, li) => {
			this.lRings[1][li] = []
			this.value.forEach(num => {
				const ro = { lt, num, ly: 'lower', ln: num + lt + (li + 1)}
				this.rings.push(ro)
				this.lRings[1][li].push(ro)
			})
		})
	}
	
	
	__calcRings() {
		if (!this.upperLayer) throw ('请先设置孔号的字母标识集')
		this.rings = []
		this.lRings = [[], []]
		if (!this.value) return
		this.upperLayer.forEach((lt, li) => {
			this.lRings[0][li] = []
			this.value.forEach(num => {
				const ro = { lt, num, ly: 'upper', ln: lt + num}
				this.rings.push(ro)
				this.lRings[0][li].push(ro)
			})
		})
		this.lowerLayer.forEach((lt, li) => {
			this.lRings[1][li] = []
			this.value.forEach(num => {
				const ro = { lt, num, ly: 'lower', ln: lt + num }
				this.rings.push(ro)
				this.lRings[1][li].push(ro)
			})
		})
	}

	/**
	 * 设置起始位置和各孔号之间的间距
	 * @param {{x0: number, y0: number, r: number}} 起始位置{第一个孔的位置x=0,y=0，半径r=10}
	 * @param {{xd: number, yd: number, td: number, ld: number}} 孔号间距{横向间隔xd=20, 纵向间距yd=20, 孔号标签间距td=10, 上下层间距ld=40} 
	 */
	setPosition({ x0=0, y0=0, r=10 } = {}, { xd=30, yd=20, td=10, ld=40 } = {}) {
		let [X, Y] = [x0 + r / 2, y0 + r / 2]
		for (let i = 0; i < this.lRings.length; i++) {
			Y += ld * i
			for (let j = 0; j < this.lRings[i].length; j++) {
				Y += yd
				for (let k = 0; k < this.lRings[i][j].length; k++) {
					const ro = this.lRings[i][j][k]
					ro.x = X + xd * k
					ro.y = Y + td
					ro.tx = ro.x - 20
					ro.ty = Y;
					ro.color = 'white'
				}
			}
		}
	}

	/**
	 * 获取孔号对象数组
	 * @returns [{lt:'A', num: 201, ly: 'lower', ln:'A201'}]
	 */
	getRings() {
		return this.rings
	}

}
